package com.bidevalution.business.job;

import com.bidevalution.business.factory.StepJobJdbcFactory;
import com.bidevalution.business.service.JdbcTemplateService;
import com.bidevalution.dao.entity.BeEvalutionExpert;
import com.bidevalution.dao.entity.BeSectionExpertInfo;
import com.bidevalution.dao.entity.BeSectionStep;
import com.bidevalution.dao.entity.BeSectionStepJob;
import com.qtp.core.util.DateUtil;
import com.qtp.core.util.IdsUtil;
import com.qtp.core.util.OConvertUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 安全文明施工措施费用评审
 * Created by glodon on 2019-09-27.
 */
public class SafeConstructionJob implements StepJobJdbcFactory {
    private JdbcTemplateService jdbcTemplateService;
    @Override
    public void setJdbcTemplateService(JdbcTemplateService jdbcTemplateService) {
        this.jdbcTemplateService = jdbcTemplateService;
    }

    @Override
    public Boolean execute(BeSectionStepJob beSectionStepJob, String submitCode,String expertId,String layouCode)
            throws Exception {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("sectionStepId", beSectionStepJob.getSectionStepId());
        paramMap.put("submitCode", submitCode);
        paramMap.put("sectionId", beSectionStepJob.getSectionId());
        //获取安全文明施工费分析明细
        List<Map<String, Object>> list  = jdbcTemplateService.selectForList("select a.mano_projectid as ProjectID, a.enterprise_id as BidID, a.mano_managenodeid as ManageNodeID,\n" +
                "         a.mano_idxcode as IdxCode, a.mano_code as Code, CONCAT(b.mano_name,'-',a.mano_name) as ManageNodeName,\n" +
                "         ifnull(vi_b.RGFTotal,0)+ifnull(vi_m.RGFTotal,0)+ifnull(vi_b.JXFTotal,0)+ifnull(vi_m.JXFTotal,0) as CostBase,\n" +
                "        c.cora_HJBHUnder as CostRate, a.mano_spectype as spectype\n" +
                "          from td_ManageNode_Bid a\n" +
                "           left join be_section_info d on a.mano_projectid = d.td_projectId\n" +
                "          left join td_ManageNode as b on a.mano_projectid=b.mano_projectid\n" +
                "                and a.mano_parentid=b.mano_managenodeid and b.mano_projectid=d.td_projectId\n" +
                "          inner join td_CostRate c on a.mano_projectid=c.cora_ProjectID\n" +
                "                and c.cora_ManageNodeID=a.mano_ManageNodeID and c.cora_ProjectID=d.td_projectId\n" +
                "          left join vi_budgetnodecost vi_b on vi_b.ProjectID=a.mano_ProjectID\n" +
                "            and vi_b.BidID=a.enterprise_id and vi_b.ManageNodeID=a.mano_ManageNodeID\n" +
                "            and vi_b.ProjectID=d.td_projectId\n" +
                "          left join vi_measuresnodecost vi_m on vi_m.ProjectID=a.mano_ProjectID\n" +
                "            and vi_m.BidID=a.enterprise_id and vi_m.ManageNodeID=a.mano_ManageNodeID\n" +
                "            and vi_m.ProjectID=d.td_projectId\n" +
                "            where d.seq_id=:sectionId and a.mano_Type=2\n" +
                "            order by a.enterprise_id,IdxCode", paramMap);
        List<Map<String, Object>> enterList = jdbcTemplateService.selectForList("SELECT a.enterprise_id enterpriseId,b.enterprise_name enterpriseName\n" +
                "FROM be_evalution_expert a \n" +
                "LEFT JOIN be_section_enterprise b ON a.enterprise_id=b.seq_id and a.section_id = b.section_id\n" +
                "WHERE b.section_id =:sectionId AND\ta.section_step_code='67' AND a.is_del='0' GROUP BY a.enterprise_id", paramMap);
        //获企业管理费单位列表
        for(Map<String, Object> map : enterList){
            Double tjRate = 0.0;
            Double tjBase = 0.0;
            int tjCount = 0;
            Double underCostTotal = 0.0;
            for(Map<String, Object> detailMap : list) {
                if(OConvertUtils.getString(map.get("enterpriseId")).equals(OConvertUtils.getString(detailMap.get("BidId")))){
                    //各单位工程取费基数
                    Double costBase = OConvertUtils.getDouble(detailMap.get("CostBase"),0.0);
                    //各单位工程费率
                    Double costRate = OConvertUtils.getDouble(detailMap.get("CostRate"),0.0);
                    //各单位工程最低金额
                    Double underCost = costBase*costRate/100;
                    //土建专业
                    if (OConvertUtils.getInt(detailMap.get("spectype")) == 1){
                        //存储费率(因为所有的土建专业费率必须一致，所以只要记录一个即可)
                        tjRate = costRate;
                        //汇总非土建专业的报价
                        tjBase += costBase;
                        tjCount++;
                    } else {
                        //汇总非土建专业的报价
                        underCostTotal += underCost;
                    }
                    map.put("CostBase", detailMap.get("CostBase"));
                }
            }
            if(tjCount > 0) {
                //最低报价汇总土建专业报价
                underCostTotal += calculateTjCost(tjBase, tjRate);
            }
            map.put("underCostTotal", underCostTotal);
        }

        //保存计算结果
        saveResult(beSectionStepJob.getSectionId(), submitCode, enterList);
        return true;
    }

    /**
     * 计算汇总土建专业最低报价
     * @param tjBase 土建基数
     * @param tjRate 土建费率
     * @return
     */
    private Double calculateTjCost(Double tjBase, Double tjRate){
        Double result;
        if(tjBase < 5000000) {
            //取费基数额度500万元已内的执行标准费率
            result = tjBase * tjRate;
        } else if (tjBase < 20000000) {
            //500万元以上至2000万按标准费率乘0.9
            result = 5000000 * tjRate;
            result += (tjBase - 5000000) * tjRate * 0.9;
        } else if (tjBase < 50000000) {
            //2000万以上至5000万按标准费率乘0.8
            result = 5000000 * tjRate;
            result += (20000000 - 5000000) * tjRate * 0.9;
            result += (tjBase - 20000000) * tjRate * 0.8;
        } else {
            //5000万元以上按标准费率乘0.7
            result = 5000000 * tjRate;
            result += (20000000 - 5000000) * tjRate * 0.9;
            result += (50000000 - 20000000) * tjRate * 0.8;
            result += (tjBase - 50000000) * tjRate * 0.7;
        }
        return result;
    }

    private void saveResult(String sectionId, String submitCode,List<Map<String, Object>> enterList) throws Exception {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("sectionId", sectionId);
        RowMapper<BeSectionExpertInfo> rm1 = BeanPropertyRowMapper.newInstance(BeSectionExpertInfo.class);
        List<BeSectionExpertInfo> beSectionExpertInfoList = jdbcTemplateService.selectForList(" select\n" +
                "    seq_id, section_id, name, login_name, card_no, work_unit, phone, expert_type, area_type,\n" +
                "    is_avoid, avoid_reason, is_manager, update_time, create_time\n" +
                "    from be_section_expert_info\n" +
                "    where section_id=:sectionId", paramMap, rm1);
        RowMapper<BeSectionStep> rm2 = BeanPropertyRowMapper.newInstance(BeSectionStep.class);
        BeSectionStep beSectionStep = jdbcTemplateService.selectForObject(" select\n" +
                "    seq_id, section_id, step_code, step_name, parent_code, order_num, step_url, related_step_code, \n" +
                "    related_layout_code, related_column_code, related_step_id, create_time, update_time,load_function" +
                "    from be_section_step\n" +
                "     where section_id=:sectionId and step_code = '58'", paramMap, rm2);
        List<BeEvalutionExpert> beEvalutionExpertList = new ArrayList<>();
        BeEvalutionExpert beEvalutionExpert = null;
        for(BeSectionExpertInfo beSectionExpertInfo: beSectionExpertInfoList){
            for(Map<String, Object> map: enterList) {
                beEvalutionExpert = new BeEvalutionExpert();
                beEvalutionExpert.setSeqId(IdsUtil.uuid());
                beEvalutionExpert.setExpertId(beSectionExpertInfo.getSeqId());
                beEvalutionExpert.setSectionId(sectionId);
                beEvalutionExpert.setColumnCode("zdje");
                beEvalutionExpert.setColumnValue(OConvertUtils.getString(map.get("underCostTotal")));
                beEvalutionExpert.setEnterpriseId(OConvertUtils.getString(map.get("enterpriseId")));
                beEvalutionExpert.setSectionStepId(beSectionStep.getSeqId());
                beEvalutionExpert.setSectionStepCode(beSectionStep.getStepCode());
                beEvalutionExpert.setLayoutCode("Top");
                beEvalutionExpert.setSubmitCode(submitCode);
                beEvalutionExpert.setCreateTime(DateUtil.now());
                beEvalutionExpert.setUpdateTime(DateUtil.now());
                beEvalutionExpertList.add(beEvalutionExpert);

                beEvalutionExpert = new BeEvalutionExpert();
                beEvalutionExpert.setSeqId(IdsUtil.uuid());
                beEvalutionExpert.setExpertId(beSectionExpertInfo.getSeqId());
                beEvalutionExpert.setColumnCode(beSectionStep.getRelatedColumnCode());
                if(OConvertUtils.getDouble(map.get("underCostTotal"), 0.0) < OConvertUtils.getDouble(map.get("CostBase"), 0.0)){
                    beEvalutionExpert.setColumnValue("0");
                } else {
                    beEvalutionExpert.setColumnValue("1");
                }
                beEvalutionExpert.setEnterpriseId(OConvertUtils.getString(map.get("enterpriseId")));
                beEvalutionExpert.setSectionId(sectionId);
                beEvalutionExpert.setSectionStepId(beSectionStep.getRelatedStepId());
                beEvalutionExpert.setSectionStepCode(beSectionStep.getRelatedStepCode());
                beEvalutionExpert.setLayoutCode(beSectionStep.getRelatedLayoutCode());
                beEvalutionExpert.setSubmitCode(submitCode);
                beEvalutionExpert.setCreateTime(DateUtil.now());
                beEvalutionExpert.setUpdateTime(DateUtil.now());
                beEvalutionExpertList.add(beEvalutionExpert);
            }
        }
        //批量转数组
        SqlParameterSource[] beanSources = SqlParameterSourceUtils.createBatch(beEvalutionExpertList);
        jdbcTemplateService.bathInsert(" insert into be_evalution_expert (seq_id, section_step_id, section_id,\n" +
                "    column_code, expert_id, column_value,submit_code,row_key,layout_code,enterprise_id,section_step_code,create_time,\n" +
                "    update_time)\n" +
                "    values(:seqId, :sectionStepId, :sectionId,:columnCode, :expertId, :columnValue,:submitCode,:rowKey," +
                "   :layoutCode,:enterpriseId,:sectionStepCode,:createTime,:updateTime)",beanSources);
    }
}
